package com.powernobug.servlet;

import com.powernobug.bean.model.MarketStorage;
import com.powernobug.bean.vo.BaseRespVo;
import com.powernobug.bean.vo.PageVo;
import com.powernobug.bean.vo.param.StorageListParam;
import com.powernobug.service.impl.StorageServiceImpl;
import com.powernobug.service.StorageService;
import com.powernobug.util.*;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.*;

/**
 * @Author: 肖云戈
 * @CreateTime: 2024-08-22
 * @Description:
 */
@MultipartConfig
@WebServlet("/storage/*")
public class StorageServlet extends HttpServlet {
    private static StorageService storageService = new StorageServiceImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String result = "";
        try {
            String uri = req.getRequestURI();
            if (uri.contains("/fetch/")) {
                fetch(req, resp);
            } else if (uri.contains("/storage/create")) {
                result = JsonUtil.writeJson(create(req));
            } else if (uri.contains("/storage/list")) {
                result = JsonUtil.writeJson(list(req));
            } else if (uri.contains("/storage/update")) {
                result = JsonUtil.writeJson(update(req));
            } else if (uri.contains("/storage/delete")) {
                result = JsonUtil.writeJson(delete(req));
            } else {
                result = JsonUtil.writeJson(BaseRespVo.errList(404));
            }

        } catch (IOException e) {
            result = JsonUtil.writeJson(BaseRespVo.errList(609));
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().write(result);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    public BaseRespVo create(HttpServletRequest req) throws ServletException, IOException {
        // 从 req 解析出 MarketStorage 对象
        Part picture = req.getPart("file");
        // 非图片禁止上传！
        if (!picture.getContentType().startsWith("image"))
            return BaseRespVo.errList(607);

        String picPath = (String) getServletContext().getAttribute(Constant.PIC_PATH);
        int methodUriLength = req.getRequestURI().length() - ((String) getServletContext().getAttribute(Constant.ROOT_DEPLOY)).length();
        String rootAddress = req.getRequestURL().reverse().delete(0, methodUriLength).reverse().toString();
        MarketStorage marketStorage = FileUtil.pictureDataPack(picture, rootAddress, picPath);
        // 新建一个指定路径的输入流对象，交给工具类完成文件写入
        InputStream picInput = picture.getInputStream();
        OutputStream output = new FileOutputStream(getFilePath(marketStorage));
        IOUtil.save(picInput, output);
        // 文件写入成功，再调用 model 层，将文件信息封装并插入数据库（记得useGeneticKey=true），获取到主键信息
        MarketStorage result = storageService.uploadFile(marketStorage);
        // 将获取到主键信息的文件信息对象，封装给BaseResqVo返回即可
        return BaseRespVo.okList(result);
    }

    public void fetch(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 从URL中解析出待上传文件的名称，然后根据该名称前往数据库查询对应的数据
        String imgName = req.getRequestURI().substring(req.getRequestURI().lastIndexOf("/") + 1);
        MarketStorage marketStorage = storageService.fetchPicture(imgName);
        if (marketStorage == null)
            throw new IOException();
        // 找到数据后，获取其本地文件路径，并使用工具类开启文件传输
        String filePath = getFilePath(marketStorage);
        resp.setContentType(marketStorage.getType());
        IOUtil.save(new FileInputStream(filePath), resp.getOutputStream());
    }

    public BaseRespVo list(HttpServletRequest req) {
        StorageListParam storageListParam = QueryParamPackageUtil.packParams(StorageListParam.class, req);
        PageVo pageVo = storageService.getStorageByPage(storageListParam);
        return BaseRespVo.okList(pageVo);
    }

    public BaseRespVo update(HttpServletRequest req) throws NoSuchFieldException, IllegalAccessException, IOException {
        MarketStorage marketStorage = JsonUtil.readJson(req.getReader().readLine(), MarketStorage.class);
        Boolean isSuccess = storageService.updateStorage(marketStorage, false);
        return isSuccess ? BaseRespVo.okList(marketStorage) : BaseRespVo.errList(608);
    }

    public BaseRespVo delete(HttpServletRequest req) throws IOException, NoSuchFieldException, IllegalAccessException {
        MarketStorage marketStorage = JsonUtil.readJson(req.getReader().readLine(), MarketStorage.class);
        marketStorage.setDeleted(true);
        Boolean isSuccess = storageService.updateStorage(marketStorage, true);
        return isSuccess ? BaseRespVo.okList(null) : BaseRespVo.errList(603);
    }

    private String getFilePath(MarketStorage marketStorage) {
        String picPath = (String) getServletContext().getAttribute(Constant.PIC_PATH);
        return picPath + "/" + marketStorage.getKey();
    }
}
